package com.ccp.dev.workflow.controller;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.consts.UrlConstants;
import com.ccp.dev.core.basic.internationalization.SysBaseController;
import com.ccp.dev.core.basic.model.SysAuditModelType;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.util.RequestUtil;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.core.util.log.SysAuditThreadLocalHolder;
import com.ccp.dev.workflow.bpmutil.BpmUtil;
import com.ccp.dev.workflow.model.*;
import com.ccp.dev.workflow.service.ActDefModelService;
import com.ccp.dev.workflow.service.BpmNodeRuleService;
import com.ccp.dev.workflow.service.BpmNodeSetService;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.RepositoryService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * ClassDescribe:
 * 流程跳转规则控制器层
 * @author :wangcheng
 * Date: 2019-07-08
 */
@Controller
@RequestMapping(UrlConstants.PROJECT_ROOT + UrlConstants.PROJECT_MODULE_WORKFLOW + "/bpmNodeRule")
@Action(ownermodel = SysAuditModelType.PROCESS_MANAGEMENT)
public class BpmNodeRuleController extends SysBaseController {
    @Resource
    private ActDefModelService actDefModelService;
    @Resource
    private BpmNodeSetService bpmNodeSetService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private BpmNodeRuleService bpmNodeRuleService;

    /**
     * 跳转节点规则编辑页面
     * @param model 前台mvc容器
     * @param request http请求
     * @return 编辑页面
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/edit")
    @Action(description = "跳转节点规则编辑页面", detail = "跳转节点规则编辑页面<#if success>成功<#else>失败</#if>")
    public String edit(Model model, HttpServletRequest request) {
        String deployId = RequestUtil.getString(request, "deployId");
        String procDefId = RequestUtil.getString(request, "procDefId");
        String nodeId = RequestUtil.getString(request, "nodeId");
        String nodeName = RequestUtil.getString(request, "nodeName");
        String parentProcDefId = RequestUtil.getString(request, "parentProcDefId","");

        //当前节点信息
        FlowNodeInfo flowNodeInfo = NodeCache.getByProcDefId(procDefId).get(nodeId);

        ActDefModel actDefModel = actDefModelService.getByProcDefId(procDefId);
        String modelId = null;
        if (actDefModel != null) {
            SysAuditThreadLocalHolder.putParamerter("success", true);
            modelId = actDefModel.getId();
        }else {
            SysAuditThreadLocalHolder.putParamerter("success", false);
        }

        // 取得可跳转的活动节点
        List<String> nodeList = new ArrayList<>();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);
        Map<String, Map<String, String>> activityList = BpmUtil.getTranstoActivitys(bpmnModel, nodeList,false);

        BpmNodeSet bpmNodeSet = bpmNodeSetService.getByProcDefIdNodeIdOrParentProcDefId(nodeId,procDefId,parentProcDefId);

        BpmNodeRule bpmNodeRule = new BpmNodeRule();
        bpmNodeRule.setProcDefId(procDefId);
        bpmNodeRule.setNodeId(nodeId);

        model.addAttribute("activityList", activityList);
        model.addAttribute("nodeName", nodeName);
        model.addAttribute("bpmNodeRule", bpmNodeRule);
        model.addAttribute("deployId", deployId);
        model.addAttribute("procDefId", procDefId);
        model.addAttribute("nodeId", nodeId);
        model.addAttribute("bpmNodeSet", bpmNodeSet);
        model.addAttribute("modelId", modelId);
        model.addAttribute("nextNodes", flowNodeInfo.getNextFlowNodesInfo());
        model.addAttribute("parentActDefId", parentProcDefId);
        return getAutoView();
    }

    /**
     * 根据流程定义id和节点ID获取流程规则列表。
     * @param request http请求
     * @return 封装集合
     */
    @RequestMapping("/getByProcDefIdNodeId")
    @Action(description = "根据流程定义id和节点ID获取流程规则列表", detail = "根据流程定义id和节点ID获取流程规则列表")
    @ResponseBody
    public ResultData getByProcDefIdNodeId(HttpServletRequest request){
        String procDefId = RequestUtil.getString(request, "procDefId");
        String nodeId = RequestUtil.getString(request, "nodeId");
        List<BpmNodeRule> bpmNodeRuleList = bpmNodeRuleService.getByProcDefIdNodeId(procDefId, nodeId);
        return getResultDataSuccess("operation.success", bpmNodeRuleList);
    }

    /**
     * 保存流程节点跳转规则
     * @param bpmNodeRule 跳转规则对象
     * @return 封装类对象
     */
    @RequestMapping("/save")
    @Action(description = "保存流程节点跳转规则", detail = "保存或更新流程节点跳转规则")
    @ResponseBody
    public ResultData save(BpmNodeRule bpmNodeRule) {
        String targetNode = bpmNodeRule.getTargetNode();
        String[] nodeStr = targetNode.split(",");
        bpmNodeRule.setTargetNode(nodeStr[0]);
        bpmNodeRule.setTargetNodeName(nodeStr[1]);
        if (StringUtil.isEmpty(bpmNodeRule.getRuleId())) {
            bpmNodeRule.setRuleId(UUIDUtils.getUUIDFor32());
            bpmNodeRule.setPriority(System.currentTimeMillis());
            bpmNodeRuleService.add(bpmNodeRule);
            return getResultDataSuccess("save.success");
        }else {
            bpmNodeRuleService.update(bpmNodeRule);
            return getResultDataSuccess("update.success");
        }
    }

    /**
     * 根据id查询跳转规则对象
     * @param ruleId 跳转规则id
     * @return 返回结果封装对象
     */
    @RequestMapping("/getById")
    @Action(description = "根据id查询跳转规则对象", detail = "根据id查询跳转规则对象")
    @ResponseBody
    public ResultData getById(@RequestParam String ruleId) {
        BpmNodeRule bpmNodeRule = bpmNodeRuleService.getOneById(ruleId);
        return getResultDataSuccess("operation.success", bpmNodeRule);
    }

    /**
     * 对跳转规则进行排序
     * @param ruleIds 规则id组合字符串
     * @return 返回结果封装对象
     */
    @RequestMapping("/sortRule")
    @Action(description = "对跳转规则进行排序", detail = "对跳转规则进行排序")
    @ResponseBody
    public ResultData sortRule(@RequestParam String ruleIds) {
        try {
            bpmNodeRuleService.reSort(ruleIds);
            return getResultDataSuccess("operation.success");
        } catch (Exception e) {
            e.printStackTrace();
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }

    /**
     * 删除流程节点跳转规则
     * @param ruleId 跳转规则id
     * @return 返回结果封装对象
     */
    @RequestMapping("/del")
    @Action(description = "删除流程节点跳转规则", detail = "删除流程节点跳转规则<#if  success>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData del(@RequestParam String ruleId) {
        try {
            bpmNodeRuleService.delById(ruleId);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("delete.success");
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("delete.failure",1,e.getMessage());
        }
    }

    /**
     * 更改跳转规则
     * @param request http请求
     * @return 返回数据封装对象
     */
    @RequestMapping("/updateIsJumpForDef")
    @Action(description = "更改跳转规则",
            detail = "流程定义【${procDefId}的节点 ${nodeId}】的跳转规则为" +
                    "<#if '1'==isJumpForDef)> 规则不符合条件时，任务按定义正常跳转" +
                    "<#elseif '0'==isJumpForDef> 规则不符合条件时，任务仅是完成当前节点，不作跳转处理" +
                    "</#if><#if success>成功<#else>失败</#if>" )
    @ResponseBody
    public ResultData updateIsJumpForDef(HttpServletRequest request) {
        String nodeId = RequestUtil.getString(request, "nodeId");
        String procDefId = RequestUtil.getString(request, "procDefId");
        String isJumpForDef = RequestUtil.getString(request, "isJumpForDef");
        SysAuditThreadLocalHolder.putParamerter("nodeId",nodeId);
        SysAuditThreadLocalHolder.putParamerter("procDefId",procDefId);
        SysAuditThreadLocalHolder.putParamerter("isJumpForDef",isJumpForDef);
        try {
            bpmNodeSetService.updateIsJumpForDef(nodeId, procDefId, new Short(isJumpForDef));
            SysAuditThreadLocalHolder.putParamerter("success",true);
            return getResultDataSuccess("operation.success");

        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success",false);
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }
}
